<?php

namespace App\Service\OpenShop\Organization;

use App\Http\Resources\OpenShop\Oranization\Web\WazZoneListResource;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationRegionMappingModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageMappingModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageModel;
use App\Models\OpenShop\Organization\OpenShopRegionManageUserMappingModel;
use App\Service\BaseService;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class WarZoneService extends BaseService
{
    /**
     * 战区列表
     *
     * @return array
     */
    public static function index(): array
    {
        $regionManageModel = OpenShopRegionManageModel::query()
                                                      ->with([
                                                          "regionMappingRel"     => function ($query) {
                                                              $query->with("organizationManageRel");
                                                          },
                                                          "regionUserMappingRel" => function ($query) {
                                                              $query->select([
                                                                  "regionId",
                                                                  "userId",
                                                                  "username",
                                                                  "type"
                                                              ]);
                                                          }
                                                      ])->get();

        return [
            "list" => WazZoneListResource::collection($regionManageModel)
        ];
    }

    /**
     * 战区详情
     *
     * @param int $id
     * @return array
     */
    public static function detail(int $id): array
    {
        $regionManageModel = OpenShopRegionManageModel::query()
                                                      ->with([
                                                          "regionMappingRel"     => function ($query) {
                                                              $query->with("organizationManageRel");
                                                          },
                                                          "regionUserMappingRel" => function ($query) {
                                                              $query->select([
                                                                  "regionId",
                                                                  "userId",
                                                                  "username",
                                                                  "type"
                                                              ]);
                                                          }
                                                      ])->where("id", $id)->first();

        return [
            "detail" => WazZoneListResource::collection([$regionManageModel])->getIterator()->current()
        ];
    }

    /**
     * @param int $uid
     * @param object $params
     * @throws Exception
     */
    public static function update(int $uid, object $params)
    {
        $regionManageModel = OpenShopRegionManageModel::query()
                                                      ->with([
                                                          "regionMappingRel"     => function ($query) {
                                                              $query->withoutGlobalScope("isDel");
                                                          },
                                                          "regionUserMappingRel" => function ($query) {
                                                              $query->withoutGlobalScope("isDel");
                                                          }
                                                      ])->where("id", $params->id)->first();

        try {
            DB::beginTransaction();

            //todo 主表变更写入
            OpenShopRegionManageModel::query()->where("id", $params->id)->update([
                "updatedAt"    => time(),
                "updatedByUid" => $uid
            ]);

            // todo 关联 省区 写入
            self::updateRegionMapping(
                $uid,
                $params->id,
                $regionManageModel->regionMappingRel->pluck("manageId")->toArray(),
                $params->organizationManageIds
            );

            // ToDo  关联 负责人 用户写入
            self::updateRegionUserMapping(
                $uid,
                $params->id,
                $regionManageModel->regionUserMappingRel->where("type",
                    OpenShopRegionManageUserMappingModel::USER_TYPE_1)
                                                        ->pluck("userId")->toArray(),
                $params->chargeUsers,
                OpenShopRegionManageUserMappingModel::USER_TYPE_1
            );

            // ToDo  关联 附属负责人 用户写入
            self::updateRegionUserMapping(
                $uid,
                $params->id,
                $regionManageModel->regionUserMappingRel->where("type",
                    OpenShopRegionManageUserMappingModel::USER_TYPE_2)
                                                        ->pluck("userId")->toArray(),
                $params->attachChargeUsers,
                OpenShopRegionManageUserMappingModel::USER_TYPE_2
            );

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            throw new $exception;
        }
    }

    /**
     * @param int $uid
     * @param int $regionId
     * @param array $existsManageIds
     * @param array $requestManageIds
     */
    private static function updateRegionMapping(
        int $uid,
        int $regionId,
        array $existsManageIds,
        array $requestManageIds
    ) {
        // todo 关联省区数据写入
        $intersectionManageIds = array_intersect($existsManageIds, $requestManageIds);
        $delManageIds          = array_diff($existsManageIds, $intersectionManageIds);

        //todo 删除未选中的数据
        if ($delManageIds) {
            OpenShopRegionManageMappingModel::query()
                                            ->where("regionId", $regionId)
                                            ->whereIn("manageId", $delManageIds)
                                            ->update([
                                                "isDeleted"    => 1,
                                                "updatedAt"    => time(),
                                                "updatedByUid" => $uid
                                            ]);

        }

        // todo  选中且已存在数据置为正常
        if ($intersectionManageIds) {
            OpenShopRegionManageMappingModel::query()
                                            ->withoutGlobalScope("isDel")
                                            ->where("regionId", $regionId)
                                            ->whereIn("manageId", $intersectionManageIds)
                                            ->update([
                                                "isDeleted"    => 0,
                                                "updatedAt"    => time(),
                                                "updatedByUid" => $uid
                                            ]);
        }

        $diffManageIds = array_diff($requestManageIds, $intersectionManageIds);
        // todo 新增数据插入
        if ($diffManageIds) {
            OpenShopRegionManageMappingModel::query()->insert(
                collect($diffManageIds)->map(function (int $manageId) use ($regionId, $uid) {
                    return [
                        "regionId"     => $regionId,
                        "manageId"     => $manageId,
                        "createdAt"    => time(),
                        "createdByUid" => $uid,
                        "updatedAt"    => time(),
                        "updatedByUid" => $uid
                    ];
                })->values()->toArray());
        }
    }


    /**
     * 关联用户写入
     *
     * @param int $uid
     * @param int $regionId
     * @param array $existsUserIds
     * @param array $requestUser
     * @param int $type
     */
    private static function updateRegionUserMapping(
        int $uid,
        int $regionId,
        array $existsUserIds,
        array $requestUser,
        int $type
    ) {
        $collectRequestUser  = collect($requestUser);
        $requestUserIds      = $collectRequestUser->pluck("userId")->toArray();
        $intersectionUserIds = array_intersect($existsUserIds, $requestUserIds);
        $delUserIds          = array_diff($existsUserIds, $intersectionUserIds);
        //todo 删除未选中的数据
        if ($delUserIds) {
            OpenShopRegionManageUserMappingModel::query()
                                                ->where("regionId", $regionId)
                                                ->where("type", $type)
                                                ->whereIn("userId", $delUserIds)
                                                ->update([
                                                    "isDeleted"    => 1,
                                                    "updatedAt"    => time(),
                                                    "updatedByUid" => $uid
                                                ]);
        }

        // todo  选中且已存在数据置为正常
        if ($intersectionUserIds) {
            OpenShopRegionManageUserMappingModel::query()
                                                ->withoutGlobalScope("isDel")
                                                ->where("regionId", $regionId)
                                                ->where("type", $type)
                                                ->whereIn("userId", $intersectionUserIds)
                                                ->update([
                                                    "isDeleted"    => 0,
                                                    "updatedAt"    => time(),
                                                    "updatedByUid" => $uid
                                                ]);
        }


        $diffUserIds = array_diff($requestUserIds, $intersectionUserIds);
        // todo 新增数据插入
        if ($diffUserIds) {
            OpenShopRegionManageUserMappingModel::query()->insert(
                collect($diffUserIds)->map(function (int $manageId) use ($regionId, $uid, $type, $collectRequestUser) {
                    $user = $collectRequestUser->where("userId", $manageId)->first();
                    return [
                        "regionId"     => $regionId,
                        "userId"       => $user["userId"],
                        "username"     => $user["username"],
                        "createdAt"    => time(),
                        "createdByUid" => $uid,
                        "updatedAt"    => time(),
                        "updatedByUid" => $uid,
                        "type"         => $type
                    ];
                })->values()->toArray());
        }
    }

    /**
     * 获取战区树结构数据
     *
     * @param int $cacheTime
     * @return mixed|void
     */
    public static function regionTree(int $cacheTime = 300)
    {
        $regionTreeFunc = function () {
            return OpenShopRegionManageModel::query()->with([
                "regionMappingRel" => function ($query) {
                    $query->with([
                        "organizationManageRel" => function ($query) {
                            $query->where("type", "<>", OpenShopOrganizationManageModel::HEADQUARTERS_ID)
                                  ->with([
                                      'regionRel'      => function ($query) {
                                          $query->where('isDeleted', 0);
                                      },
                                      'managerUserRel' => function ($query) {
                                          $query->where('isDeleted', 0);
                                      }
                                  ]);
                        }
                    ]);
                },
                "regionUserMappingRel"
            ])->get();
        };


        if ($cacheTime > 0) {
            return Cache::remember(vsprintf("%s:%s:%s", [
                __FUNCTION__,
                "all",
                $cacheTime
            ]), getSwitchCacheTime($cacheTime), function () use ($regionTreeFunc) {
                return $regionTreeFunc();
            });
        } else {
            return $regionTreeFunc();
        }
    }

    /**
     * 根据省区code获得战区
     */
    public static function getWarZoneInfoByProvinceCode(int $provinceCode, array $fields = [])
    {
        // 根据code获得省区组织
        $provinceManageId = (int)OpenShopOrganizationRegionMappingModel::query()
            ->where("provinceCode", $provinceCode)
            ->value('manageId');

        // 根据组织管理获得绑定的战区
        return OpenShopRegionManageMappingModel::query()
            ->where('manageId', $provinceManageId)
            ->when(!empty($fields), function ($query) use ($fields) {
                $query->select($fields);
            })
            ->first();
    }

    public static function getWarZoneDistrictList()
    {
        $orgManageList = OpenShopOrganizationManageModel::query()
                                                        ->with('regionRel')
                                                        ->get()
                                                        ->map(function ($item) {
                                                            $item->provinceCode = $item->regionRel[0]->provinceCode ?? '';
                                                            $item->provinceName = $item->regionRel[0]->provinceName ?? '';
                                                            return $item;
                                                        })->keyBy('id')->toArray();

        return OpenShopRegionManageModel::query()
                                        ->with('regionMappingRel')
                                        ->get()
                                        ->map(function ($item) use ($orgManageList) {
                                            return [
                                                'id'           => $item->id,
                                                'name'         => $item->name,
                                                'provinceList' => collect($item->regionMappingRel)
                                                    ->map(function ($map) use ($orgManageList) {
                                                        return [
                                                            'provinceCode' => $orgManageList[$map->manageId]['provinceCode'] ?? '',
                                                            'provinceName' => $orgManageList[$map->manageId]['provinceName'] ?? '',
                                                        ];
                                                    })->toArray()
                                            ];
                                        })->toArray();
    }

}
